<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div id="chart" height="400" width="700" style="margin:50px"></div>
    
    <script type="text/javascript">
        function goChart(cBox,dataArr,textArr){
            // 声明所需变量
            var canvas,ctx;
            // 图表属性
            var cWidth, cHeight, cMargin, cSpace;
            var originX, originY;
            // 柱状图属性
            var bMargin, tobalBars, bWidth, maxXValue, maxYValue, minXValue, minYValue;
            var totalNomber;
            var yAverage, minTrueYValue, maxTrueYValue;

            // 运动相关变量
            var ctr, numctr, speed;
            //鼠标移动
            var mousePosition = {};
            
        	// 创建canvas并获得canvas上下文
	       	canvas = document.createElement("canvas");
	       	if(canvas && canvas.getContext){
                ctx = canvas.getContext("2d");
            }
	       	
	       	canvas.innerHTML = "你的浏览器不支持HTML5 canvas";
	       	cBox.appendChild(canvas);
            
            initChart(); // 图表初始化
            drawLineLabelMarkers(); // 绘制图表轴、标签和标记
            drawChartAnimate(); // 绘制柱状图的动画
            //检测鼠标移动
            var mouseTimer = null;
            canvas.addEventListener("mousemove",function(e){
                e = e || window.event;
                if( e.offsetX || e.offsetX==0 ){
                    mousePosition.x = e.offsetX;
                    mousePosition.y = e.offsetY;
                }else if( e.layerX || e.layerX==0 ){
                    mousePosition.x = e.layerX;
                    mousePosition.y = e.layerY;
                }
                
                clearTimeout(mouseTimer);
                mouseTimer = setTimeout(function(){
                    ctx.clearRect(0,0,canvas.width, canvas.height);
                    drawLineLabelMarkers();
                    drawChartAnimate(true);
                },10);
            });

            //点击刷新图表
            canvas.onclick = function(){
                initChart(); // 图表初始化
                drawLineLabelMarkers(); // 绘制图表轴、标签和标记
                drawChartAnimate(); // 绘制折线图的动画
            };


            // 图表初始化
            function initChart(){
                // 图表信息
                cMargin = 60;
		        cSpace = 80;
		        //将canvas扩大2倍，然后缩小，以适应高清屏幕
		        canvas.width = cBox.getAttribute("width")* 2 ;
		        canvas.height = cBox.getAttribute("height")* 2;
		        canvas.style.height = canvas.height/2 + "px";
		        canvas.style.width = canvas.width/2 + "px";
		        cHeight = canvas.height - cMargin*2 - cSpace;
		        cWidth = canvas.width - cMargin*2 - cSpace;
		        originX = cMargin + cSpace;
		        originY = cMargin + cHeight;

                // 柱状图信息
                bMargin = canvas.width/40;
                tobalBars = dataArr.length;
                bWidth = parseInt( cWidth/tobalBars - bMargin );
                maxXValue = 0;
                maxYValue = 0;
                var xArr = [];
                var yArr = [];
                for(var i=0; i<dataArr.length; i++){
                    xArr.push( dataArr[i][0] );
                    yArr.push( dataArr[i][1] );
                }
                yAverage = ( eval(yArr.join("+"))/yArr.length ).toFixed(2);
                var addNb = parseInt(yAverage/10); //用于在轴前后加空白
                
                minXValue = Math.min.apply(null,xArr); //求最小值
                minXValue = parseInt(Math.max(minXValue-addNb, 0)); //如果减去addNb后小于零，就取零
                maxXValue = parseInt(Math.max.apply(null,xArr)+addNb); //用于轴的显示，所以取整
                
                minYValue = minTrueYValue = Math.min.apply(null,yArr);
                minYValue = parseInt(Math.max(minYValue-addNb, 0));
                maxTrueYValue = Math.max.apply(null,yArr);
                maxYValue = parseInt(maxTrueYValue+addNb);
                
                totalNomber = 5;
                // 运动相关
                ctr = 1;
                numctr = 50;
                speed = 1.5;

            }

            // 绘制图表轴、标签和标记
            function drawLineLabelMarkers(){
                //ctx.translate(0.5,0.5);  // 当只绘制1像素的线的时候，坐标点需要偏移，这样才能画出1像素实线
                ctx.font = "24px Arial";
                ctx.lineWidth = 2;
                ctx.fillStyle = "#000";
                ctx.strokeStyle = "#000";
                // y轴
                drawLine(originX, originY, originX, cMargin);
                // x轴
                drawLine(originX, originY, originX+cWidth, originY);

                // 绘制标记
                drawMarkers();
                //ctx.translate(-0.5,-0.5);  // 还原位置
            }

            // 画线的方法
            function drawLine(x, y, X, Y){
                ctx.beginPath();
                ctx.moveTo(x, y);
                ctx.lineTo(X, Y);
                ctx.stroke();
                ctx.closePath();
            }

            // 绘制标记
            function drawMarkers(){
                ctx.strokeStyle = "#E0E0E0";
                // 绘制 y
                var oneYVal = (maxYValue-minYValue)/totalNomber;
                
                ctx.textAlign = "right";
                for(var i=0; i<=totalNomber; i++){
                    var markerVal = parseInt(i*oneYVal+minYValue);
                    var xMarker = originX-10;
                    var yMarker = parseInt( originY-cHeight*(markerVal-minYValue)/(maxYValue-minYValue) );
                    
                    ctx.fillText(markerVal, xMarker, yMarker+3, cSpace); // 文字
                    
                    if(i>0){
                        drawLine(originX+2, yMarker, originX+cWidth, yMarker);
                    }
                }
                
                // 绘制 x
                var oneXVal = (maxXValue-minXValue)/totalNomber;
                ctx.textAlign = "center";
                for(var i=0; i<=totalNomber; i++){
                	
                    var markerVal =  parseInt(i*oneXVal+minXValue);
                    var xMarker = parseInt( originX+cWidth*(markerVal-minXValue)/(maxXValue-minXValue));
                    var yMarker = originY+30;
                    ctx.fillText(markerVal, xMarker, yMarker, cSpace); // 文字
                    
                    if(i>0){
                        drawLine(xMarker, cMargin, xMarker, originY-2);
                    }
                }
                
                // 绘制标题 y
                ctx.save();
                ctx.rotate(-Math.PI/2);
                ctx.fillText(textArr[1], -canvas.height/2, cSpace-10);
                ctx.restore();
                // 绘制标题 x
                ctx.fillText(textArr[0], originX+cWidth/2, originY+cSpace/2+30);
            };

            //绘制动画图
            function drawChartAnimate(mouseMove){
            	
                var ifTip = false;
                var tipArr = null;
                
                for(var i=0; i<dataArr.length; i++){
                    
                    ctx.fillStyle = "rgba(46,199,201,0.5)";
                    var oX = originX+cWidth*(dataArr[i][0]-minXValue)/(maxXValue-minXValue);
                    var oY = originY - cHeight*(dataArr[i][1]-minYValue)/(maxYValue-minYValue);
                    ctx.beginPath();
                    
                    ctx.arc(oX,oY,10*ctr/numctr,0, Math.PI*2,true);
                    
                    if(!ifTip && mouseMove && ctx.isPointInPath(mousePosition.x*2, mousePosition.y*2)){ //如果是鼠标移动的到柱状图上，重新绘制图表
	                    ctx.fillStyle = "rgba(46,199,201,1)";
	                    //是否绘制提示
	                    ifTip = true;
	                    tipArr = dataArr[i];
	                }else{
	                    ctx.fillStyle = "rgba(46,199,201,0.5)";
	                }
                    ctx.fill();
                    
                }
                
                //绘制平均值线
                drawAverageLine();
                //绘制提示
                ifTip && drawTips(mousePosition.x*2, mousePosition.y*2,tipArr[0],tipArr[1]);
                
                if(ctr<numctr){
                    ctr++;
                    setTimeout(function(){
                        ctx.clearRect(0,0,canvas.width, canvas.height);
                        drawLineLabelMarkers();
                        drawChartAnimate();
                    }, speed*=1.08);
                }
            }
            
            //绘制平均值线
            function drawAverageLine(){
                ctx.beginPath();
                var yNb = originY-cHeight*(yAverage-minYValue)/(maxYValue-minYValue);
                var xNb = originX+cWidth*ctr/numctr+cMargin/2;
                ctx.moveTo(originX+2,yNb);
                ctx.lineTo(xNb,yNb);
                
                //设置虚线
                ctx.save();
                ctx.lineWidth = 4;
                ctx.strokeStyle = ctx.fillStyle = "#2ec7c9";
                ctx.setLineDash([10]);
                ctx.stroke();
                
                //绘制三角
                ctx.beginPath();
                ctx.moveTo(xNb,yNb);
                ctx.lineTo(xNb-5,yNb-8);
                ctx.lineTo(xNb+12,yNb);
                ctx.lineTo(xNb-5,yNb+8);
                ctx.fill();
                
                //绘制文本
                ctx.font = "24px Arial";
                ctx.fillText(yAverage, xNb-10,yNb-10);
                //还原
                ctx.restore();
            }
            
            //绘制提示框
            function drawTips(oX,oY,xVal,yVal){
        		ctx.save();
            	ctx.beginPath();
            	ctx.fillStyle = "rgba(0,0,0,0.5)";
            	var H = 100;
            	roundedRect(ctx,oX+10,oY-H/2,2*H,H,5);
            	
            	ctx.fillStyle = "#fff";
            	ctx.fillText(textArr[1]+"："+yVal, oX+H,oY-H/10);
            	ctx.fillText(textArr[0]+"："+xVal, oX+H,oY+H/4);
            	ctx.restore();
            }
            
            //绘制圆角矩形的方法
	        function roundedRect(ctx,x,y,width,height,radius){
	            ctx.moveTo(x,x+radius);
	            ctx.beginPath();
	            ctx.lineTo(x,y+height-radius);
	            ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
	            ctx.lineTo(x+width-radius, y+height);
	            ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
	            ctx.lineTo(x+width,y+radius);
	            ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
	            ctx.lineTo(x+radius,y);
	            ctx.quadraticCurveTo(x,y,x,y+radius);
	            ctx.closePath();
	            ctx.fill();
	        }

        }

		var dataArr = [[174.0, 65.6], [175.3, 71.8], [193.5, 80.7], [186.5, 72.6], [187.2, 78.8],
                [181.5, 74.8], [184.0, 86.4], [184.5, 78.4], [175.0, 62.0], [184.0, 81.6],
                [180.0, 76.6], [177.8, 83.6], [192.0, 90.0], [176.0, 74.6], [174.0, 71.0],
                [184.0, 79.6], [192.7, 93.8], [171.5, 70.0], [173.0, 72.4], [176.0, 85.9],
                [176.0, 78.8], [180.5, 77.8], [172.7, 66.2], [176.0, 86.4], [173.5, 81.8],
                [178.0, 89.6], [180.3, 82.8], [180.3, 76.4], [164.5, 63.2], [173.0, 60.9],
                [183.5, 74.8], [175.5, 70.0], [188.0, 72.4], [189.2, 84.1], [172.8, 69.1],
                [170.0, 59.5], [182.0, 67.2], [170.0, 61.3], [177.8, 68.6], [184.2, 80.1],
                [186.7, 87.8], [171.4, 84.7], [172.7, 73.4], [175.3, 72.1], [180.3, 82.6],
                [182.9, 88.7], [188.0, 84.1], [177.2, 94.1], [172.1, 74.9], [167.0, 59.1],
                [169.5, 75.6], [174.0, 86.2], [172.7, 75.3], [182.2, 87.1], [164.1, 55.2],
                [163.0, 57.0], [171.5, 61.4], [184.2, 76.8], [174.0, 86.8], [174.0, 72.2],
                [177.0, 71.6], [186.0, 84.8], [167.0, 68.2], [171.8, 66.1], [182.0, 72.0],
                [167.0, 64.6], [177.8, 74.8], [164.5, 70.0], [192.0, 101.6], [175.5, 63.2],
                [171.2, 79.1], [181.6, 78.9], [167.4, 67.7], [181.1, 66.0], [177.0, 68.2],
                [174.5, 63.9], [177.5, 72.0], [170.5, 56.8], [182.4, 74.5], [197.1, 90.9],
                [180.1, 93.0], [175.5, 80.9], [180.6, 72.7], [184.4, 68.0], [175.5, 70.9],
                [180.6, 72.5], [177.0, 72.5], [177.1, 83.4], [181.6, 75.5], [176.5, 73.0],
                [175.0, 70.2], [174.0, 73.4], [165.1, 70.5], [177.0, 68.9], [192.0, 102.3],
                [176.5, 68.4], [169.4, 65.9], [182.1, 75.7], [179.8, 84.5], [175.3, 87.7],
                [184.9, 86.4], [177.3, 73.2], [167.4, 53.9], [178.1, 72.0], [168.9, 55.5],
                [157.2, 58.4], [180.3, 83.2], [170.2, 72.7], [177.8, 64.1], [172.7, 72.3],
                [165.1, 65.0], [186.7, 86.4], [165.1, 65.0], [174.0, 88.6], [175.3, 84.1],
                [185.4, 66.8], [177.8, 75.5], [180.3, 93.2], [180.3, 82.7], [177.8, 58.0],
                [177.8, 79.5], [177.8, 78.6], [177.8, 71.8], [177.8, 116.4], [163.8, 72.2],
                [188.0, 83.6], [198.1, 85.5], [175.3, 90.9], [166.4, 85.9], [190.5, 89.1],
                [166.4, 75.0], [177.8, 77.7], [179.7, 86.4], [172.7, 90.9], [190.5, 73.6],
                [185.4, 76.4], [168.9, 69.1], [167.6, 84.5], [175.3, 64.5], [170.2, 69.1],
                [190.5, 108.6], [177.8, 86.4], [190.5, 80.9], [177.8, 87.7], [184.2, 94.5],
                [176.5, 80.2], [177.8, 72.0], [180.3, 71.4], [171.4, 72.7], [172.7, 84.1],
                [172.7, 76.8], [177.8, 63.6], [177.8, 80.9], [182.9, 80.9], [170.2, 85.5],
                [167.6, 68.6], [175.3, 67.7], [165.1, 66.4], [185.4, 102.3], [181.6, 70.5],
                [172.7, 95.9], [190.5, 84.1], [179.1, 87.3], [175.3, 71.8], [170.2, 65.9],
                [193.0, 95.9], [171.4, 91.4], [177.8, 81.8], [177.8, 96.8], [167.6, 69.1],
                [167.6, 82.7], [180.3, 75.5], [182.9, 79.5], [176.5, 73.6], [186.7, 91.8],
                [188.0, 84.1], [188.0, 85.9], [177.8, 81.8], [174.0, 82.5], [177.8, 80.5],
                [171.4, 70.0], [185.4, 81.8], [185.4, 84.1], [188.0, 90.5], [188.0, 91.4],
                [182.9, 89.1], [176.5, 85.0], [175.3, 69.1], [175.3, 73.6], [188.0, 80.5],
                [188.0, 82.7], [175.3, 86.4], [170.5, 67.7], [179.1, 92.7], [177.8, 93.6],
                [175.3, 70.9], [182.9, 75.0], [170.8, 93.2], [188.0, 93.2], [180.3, 77.7],
                [177.8, 61.4], [185.4, 94.1], [168.9, 75.0], [185.4, 83.6], [180.3, 85.5],
                [174.0, 73.9], [167.6, 66.8], [182.9, 87.3], [160.0, 72.3], [180.3, 88.6],
                [167.6, 75.5], [186.7, 101.4], [175.3, 91.1], [175.3, 67.3], [175.9, 77.7],
                [175.3, 81.8], [179.1, 75.5], [181.6, 84.5], [177.8, 76.6], [182.9, 85.0],
                [177.8, 102.5], [184.2, 77.3], [179.1, 71.8], [176.5, 87.9], [188.0, 94.3],
                [174.0, 70.9], [167.6, 64.5], [170.2, 77.3], [167.6, 72.3], [188.0, 87.3],
                [174.0, 80.0], [176.5, 82.3], [180.3, 73.6], [167.6, 74.1], [188.0, 85.9],
                [180.3, 73.2], [167.6, 76.3], [183.0, 65.9], [183.0, 90.9], [179.1, 89.1],
                [170.2, 62.3], [177.8, 82.7], [179.1, 79.1], [190.5, 98.2], [177.8, 84.1],
                [180.3, 83.2], [180.3, 83.2]
            ];
            
		/*
		 * 参数1 ：需要显示canvas的dom  (非canvas标签，需要指定height和width)
		 * 参数2：二维数据  [0]横轴   [1]纵轴
		 * 参数3：横轴名称 纵轴名称
		 * */
        goChart(document.getElementById("chart"),dataArr,["身 高","体 重"])


    </script>
</body>
</html>
